package config

import (
	"acs/taskprocess/storage"
	"fmt"
	"os"

	"github.com/BurntSushi/toml"
	"github.com/jessevdk/go-flags"
)

const (
	DefaultMaxAppConnections = int32(20000)

	// DefaultConcurrencyTaskProcessors default concurrent task processors.
	DefaultConcurrencyTaskProcessors = 100
)

var (
	Conf       *Config
	ConfigFile string
	githash    string
	buildstamp string
)

// DataLoggerConfig 数据通信log配置
type DataLoggerConfig struct {
	Level          string
	Path           string
	MaxSizeOneFile int
}

type HookConfig struct {
	EtcdHosts       []string `toml:"etcds"`
	ServiceName     string   `toml:"service_name"`
	RPCSecret       string   `toml:"rpc_secret"`
	RPCVersion      string   `toml:"version"`
	SenderKey       string   `toml:"app_senderkey"`
	SecretKey       string   `toml:"app_seckey"`
	Register        bool     `toml:"register"`
	RegisterClass   string   `toml:"register_class"`
	UnRegister      bool     `toml:"unregister"`
	UnRegisterClass string   `toml:"unregister_class"`
}

type Config struct {
	AppConfServerBind            string         `toml:"app_conf_server_bind"`
	WnetAddress                  string         `toml:"wnet_address"`
	ControlServerBind            string         `toml:"control_server_bind"`
	DataEncryptIV                string         `toml:"data_encrypt_iv"`
	DataEncryptKey               string         `toml:"data_encrypt_key"`
	EventBrokerEndpoints         []string       `toml:"event_broker_endpoints"`
	EventBrokerAuthinfo          string         `toml:"event_broker_authinfo"`
	TaskServerQueueServerLookupd []string       `toml:"task_queue_server_lookupd"`
	TaskQueueTopic               string         `toml:"task_queue_topic"`
	TaskQueueChannel             string         `toml:"task_queue_channel"`
	StorageMgo                   storage.Config `toml:"storage_mgo"`
	CtrlEventKey                 string         `toml:"ctrl_event_key"`
	EventBrokerHeartBeatTTL      int64          `toml:"event_broker_heartbeat_ttl"`
	NodesMonitorDir              string         `toml:"nodes_monitor_dir"`
	ClientListShard              int            `toml:"client_list_shard"`
	MaxProtoSize                 uint32         `toml:"max_proto_size"`
	HeartBeatTimeout             int64          `toml:"heart_beat_timeout"`
	MaxReqRespTimeout            uint32         `toml:"max_request_response_timeout"`
	// MaxTansDataIoTimeout 每次事务数据网络I/O超时时间,如果超时则认为连接已不可用.单位:毫秒,默认3000.
	MaxTansDataIoTimeout   uint32           `toml:"max_trans_io_timeout"`
	MaxAppConnections      int32            `toml:"max_app_connections"`
	ClientHandshakeTimeout uint32           `toml:"client_handshake_timeout"`
	LogLevels              string           `toml:"log_level"`
	EventExpiration        int64            `toml:"event_expiration"`
	DebugAddr              string           `toml:"debug_addr"`
	DataLogger             DataLoggerConfig `toml:"data_logger"`
	EventProcessorCount    uint32           `toml:"event_processor_count"`
	Hook                   HookConfig       `toml:"hook"`
}

func InitConfig() *Config {
	var argOpts struct {
		ConfigFile string `short:"c" long:"config-file" description:"set config file path" default:"./conf/config.toml" value-name:"FILE"`
		ShowHelp   bool   `short:"h" long:"help" description:"show this help message"`
		ShowVer    bool   `short:"V" long:"version" description:"show version information."`
	}
	argParser := flags.NewNamedParser("ACS", flags.IgnoreUnknown|flags.PrintErrors|flags.PassDoubleDash)
	_, err := argParser.AddGroup("configs", "", &argOpts)
	if err != nil {
		panic(err)
	}
	_, err = argParser.Parse()
	if err != nil {
		panic(err)
	}
	if argOpts.ShowHelp {
		argParser.WriteHelp(os.Stdout)
		os.Exit(0)
	}

	if argOpts.ShowVer {
		fmt.Printf("%v %v\r\n", githash, buildstamp)
		os.Exit(0)
	}

	ConfigFile = argOpts.ConfigFile

	config := new(Config)
	if _, err := toml.DecodeFile(ConfigFile, config); err != nil {
		panic(err)
	}
	if config.HeartBeatTimeout <= 0 {
		config.HeartBeatTimeout = 10000
	}
	if config.MaxProtoSize <= 0 {
		config.MaxProtoSize = 1024 * 1024
	}

	if config.MaxReqRespTimeout <= 0 {
		config.MaxReqRespTimeout = 8000
	}

	if config.MaxAppConnections <= 0 {
		config.MaxAppConnections = DefaultMaxAppConnections
	}
	if config.DebugAddr == "" {
		config.DebugAddr = ":7111"
	}
	if config.EventProcessorCount == 0 {
		config.EventProcessorCount = uint32(DefaultConcurrencyTaskProcessors)
	}

	if config.MaxTansDataIoTimeout == 0 {
		config.MaxTansDataIoTimeout = 3000
	}
	Conf = config
	return config
}
